package com.ruoyi.ring.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson2.JSONArray;
import com.ruoyi.common.enums.TimeUnitEnums;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.bean.Builder;
import com.ruoyi.ring.domain.RingHrv;
import com.ruoyi.ring.domain.RingHrvInfo;
import com.ruoyi.ring.domain.RingSleepDetail;
import com.ruoyi.ring.domain.dto.GeneralSecondDTO;
import com.ruoyi.ring.domain.dto.RingHrvInfoDTO;
import com.ruoyi.ring.domain.dto.RingSleepDetailInfoDTO;
import com.ruoyi.ring.domain.vo.*;
import com.ruoyi.ring.mapper.RingHrvInfoMapper;
import com.ruoyi.ring.mapper.RingHrvMapper;
import com.ruoyi.ring.mapper.RingSleepDetailMapper;
import com.ruoyi.ring.service.IHrvSecondService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class HrvSecondServiceImpl implements IHrvSecondService {
    @Resource
    private RingSleepDetailMapper sleepDetailMapper;
    @Resource
    private RingHrvMapper hrvMapper;
    @Resource
    private RingHrvInfoMapper hrvInfoMapper;
    @Override
    public List<CalendarResultVO> queryCalendarList(GeneralSecondDTO secondDTO) {
        List<RingHrvInfo>  ringHrvInfoList = hrvInfoMapper.selectRingHrvInfoList(Builder.of(RingHrvInfo::new).with(RingHrvInfo::setDeviceSn, secondDTO.getDeviceSn()).build());
        List<CalendarResultVO> resultVOS = Convert.toList(CalendarResultVO.class,ringHrvInfoList);
        ZoneId zoneId = ZoneId.systemDefault();
        List<CalendarResultVO> list = resultVOS.stream()
                .collect(Collectors.toMap(
                        vo -> vo.getDailyValue().toInstant().atZone(zoneId).toLocalDate(),
                        Function.identity(),
                        (existing, replacement) -> existing
                ))
                .values()
                .stream()
                // 使用Comparator.comparing指定按日期正序
                .sorted(Comparator.comparing(vo -> vo.getDailyValue().toInstant().atZone(zoneId).toLocalDate()))
                .collect(Collectors.toList());
        return list;
    }
    @Override
    public GeneralAverageVO queryHrvAverage(GeneralSecondDTO secondDTO) {
        GeneralAverageVO averageVO = new GeneralAverageVO();
        //自动测量
        List<RingHrvInfo>  ringHrvInfoList = hrvInfoMapper.queryRingHrvInfoList(Builder.of(RingHrvInfoDTO::new).
                with(RingHrvInfoDTO::setDeviceSn, secondDTO.getDeviceSn()).
                with(RingHrvInfoDTO::setHistoryDay, secondDTO.getRecordDate()).
                with(RingHrvInfoDTO::setType, secondDTO.getType()).build());
        List<Integer> hrvInfoList = new ArrayList<>();
        int average = 0;
        int maxValue;
        int minValue;
        List<GeneralAverageVO.ManualInfoVO> manualInfoVOList = new ArrayList<>();
        List<GeneralAverageVO.AutomaticInfoVO> automaticInfoVOList = new ArrayList<>();
        if("1".equals(secondDTO.getType())){
            //睡眠信息
            RingSleepDetail sleepDetail = sleepDetailMapper.querySleepInfoDetail(Builder.of(RingSleepDetailInfoDTO::new).
                    with(RingSleepDetailInfoDTO::setDeviceSn, secondDTO.getDeviceSn()).
                    with(RingSleepDetailInfoDTO::setDailyValue, secondDTO.getRecordDate()).build());
            if(sleepDetail != null) {
                averageVO.setEndTime(DateUtils.convertDateTimeToHHMM(sleepDetail.getEndDate()));
            }
            if(ringHrvInfoList.size() > 0) {
                RingHrvInfo hrvInfo = ringHrvInfoList.get(0);
                String[] hrvInfos = hrvInfo.getHrvList().replace("null", "0").replace("255", "0").split(",");//转成String数组
                hrvInfoList = Arrays.stream(hrvInfos).map(Integer::parseInt).collect(Collectors.toList());
                average = Convert.toInt(hrvInfoList.stream().filter(num -> num != 0).mapToInt(Integer::intValue).average().orElse(0.0));
                int timeInterval = 24*60/hrvInfoList.size();
                for(int i = 0; i< hrvInfoList.size(); i++){
                    GeneralAverageVO.AutomaticInfoVO automaticInfoVO = new GeneralAverageVO.AutomaticInfoVO();
                    int bo = hrvInfoList.get(i);
                    // 计算当前时间（分钟）：初始0分钟，每次增加5分钟
                    int minutes = i * timeInterval;
                    // 格式化时间为HH:MM格式（补前导零）
                    automaticInfoVO.setCode(DateUtils.convertMinutesToHHMM(minutes));
                    automaticInfoVO.setValue(bo);
                    automaticInfoVOList.add(automaticInfoVO);
                }
            }
            //手动测量
            List<RingHrv> hrvList = hrvMapper.queryHrvList(secondDTO);
            for (RingHrv detail : hrvList){
                int value = detail.getRealHrv();
                GeneralAverageVO.ManualInfoVO manualInfoVO = new GeneralAverageVO.ManualInfoVO();
                manualInfoVO.setCode(DateUtils.convertDateTimeToHHMM(detail.getEndTime()));
                manualInfoVO.setValue(Convert.toStr(value));
                manualInfoVOList.add(manualInfoVO);
                hrvInfoList.add(value);
            }
            maxValue = hrvInfoList.stream().filter(num -> num != 0).max(Integer::compare).orElse(0);
            minValue = hrvInfoList.stream().filter(num -> num != 0).min(Integer::compare).orElse(0);
            averageVO.setMaxValue(maxValue);
            averageVO.setMinValue(minValue);
            averageVO.setRecordDate(DateUtils.dateTimeChinese(secondDTO.getRecordDate()));
            averageVO.setWeekName(DateUtils.queryWeekday(secondDTO.getRecordDate()));
        }else {
            List<Integer> total = new ArrayList<>();
            for (RingHrvInfo hrvInfo : ringHrvInfoList){
                GeneralAverageVO.AutomaticInfoVO automaticInfoVO = new GeneralAverageVO.AutomaticInfoVO();
                String[] hrvInfos = hrvInfo.getHrvList().replace("null", "0").replace("255", "0").split(",");//转成String数组
                hrvInfoList = Arrays.stream(hrvInfos).map(Integer::parseInt).collect(Collectors.toList());
                total.addAll(hrvInfoList);
                if("2".equals(secondDTO.getType())) automaticInfoVO.setCode(DateUtils.convertDateToMMdd(hrvInfo.getDailyValue()));
                if("3".equals(secondDTO.getType())) automaticInfoVO.setCode(DateUtils.queryMonthday(hrvInfo.getDailyValue()));
                maxValue = hrvInfoList.stream().filter(num -> num != 0).max(Integer::compare).orElse(0);
                minValue = hrvInfoList.stream().filter(num -> num != 0).min(Integer::compare).orElse(0);
                automaticInfoVO.setMaxValue(maxValue);
                automaticInfoVO.setMinValue(minValue);
                automaticInfoVOList.add(automaticInfoVO);
            }
            average = Convert.toInt(total.stream().filter(num -> num != 0).mapToInt(Integer::intValue).average().orElse(0.0));
            Date dateStart = TimeUnitEnums.WEEK.getCode().equals(secondDTO.getType()) ? DateUtils.getWeekStart(secondDTO.getRecordDate(), ZoneId.systemDefault()) : DateUtils.getMonthStart(secondDTO.getRecordDate(), ZoneId.systemDefault());
            Date dateEnd = TimeUnitEnums.WEEK.getCode().equals(secondDTO.getType()) ? DateUtils.getWeekEnd(secondDTO.getRecordDate(), ZoneId.systemDefault()) : DateUtils.getMonthEnd(secondDTO.getRecordDate(), ZoneId.systemDefault());
            averageVO.setDateStart(DateUtils.dateTimeChinese(dateStart) + "，" + DateUtils.queryWeekday(dateStart));
            averageVO.setDateEnd(DateUtils.dateTimeChinese(dateEnd) + "，" + DateUtils.queryWeekday(dateEnd));

        }
        averageVO.setAverage(average);
        averageVO.setManualInfoVOS(manualInfoVOList);
        averageVO.setAutomaticInfoVOS(automaticInfoVOList);
        return averageVO;
    }


    @Override
    public  List<GeneralInfoListVO> queryHrvInfoList(GeneralSecondDTO secondDTO) {
        List<GeneralInfoListVO> list = new ArrayList<>();
        List<GeneralGroupVO> groupVOList = hrvMapper.queryHrvDetailList(secondDTO);
        for (GeneralGroupVO group : groupVOList) {
            GeneralInfoListVO infoListVO = new GeneralInfoListVO();
//            infoListVO.setDateStart(group.getDateStart());
//            infoListVO.setDateEnd(group.getDateEnd());
            infoListVO.setDailyValue(group.getDailyValue());
            infoListVO.setWeekName(group.getWeekName());
            String groupData = group.getGroupData(); // 包含多条记录的JSON数组
            // 解析JSON数组为具体的实体类（假设有子实体类）
            if(groupData != null){
                JSONArray jsonArray = JSONArray.parseArray(groupData);
                List<JsonObjectVO> jsonObjectVOList = jsonArray.toJavaList(JsonObjectVO.class);
//                infoListVO.setJsonObjectVOList(jsonObjectVOList.stream().sorted().collect(Collectors.toList()));
                jsonObjectVOList = jsonObjectVOList.stream().sorted(Comparator.comparingLong(JsonObjectVO::getId).reversed()).collect(Collectors.toList());
                infoListVO.setJsonObjectVOList(jsonObjectVOList);
            }
            list.add(infoListVO);
        }
        return list;
    }

    @Override
    public GeneralDetailListVO queryHrvDetail(Long id) {
        RingHrv hrv = hrvMapper.selectRingHrvById(id);
        GeneralDetailListVO bloodOxygenDetailVO = Convert.convert(GeneralDetailListVO.class,hrv);
        bloodOxygenDetailVO.setGeneralValue(hrv.getRealHrv());
        bloodOxygenDetailVO.setWeek(DateUtils.queryWeekday(hrv.getDailyValue()));
        bloodOxygenDetailVO.setEndHm(DateUtils.convertDateTimeToHHMM(hrv.getEndTime()));
        return bloodOxygenDetailVO;
    }

    @Override
    public List<Integer> queryHrvSevenInfo(GeneralSecondDTO secondDTO) {
        List<RingHrv> hrvList = hrvMapper.queryHrvSevenInfo(secondDTO.getDeviceSn(),new Date());
        List<Integer> hrvs = hrvList.stream().map(RingHrv::getRealHrv).collect(Collectors.toList());
        return hrvs;
    }

}
